package com.wu.config;

import com.dangdang.ddframe.rdb.sharding.api.ShardingDataSourceFactory;
import com.dangdang.ddframe.rdb.sharding.api.rule.DataSourceRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.ShardingRule;
import com.dangdang.ddframe.rdb.sharding.api.rule.TableRule;
import com.dangdang.ddframe.rdb.sharding.api.strategy.table.TableShardingStrategy;
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.IdGenerator;

import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;

/**
 * @author wufei
 * @date 2018/3/29/029 14:41
 */
@Configuration
public class DataSourceConfig {

    @Bean(name="dataSource0")
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource0(){
        return DataSourceBuilder.create().build();
    }

    @Bean(name="dataSource")
    public  DataSource buildDataSource() {
        //设置分库映射
        Map<String, DataSource> dataSourceMap = new HashMap<>(1);
        //添加两个数据库ds_0,ds_1到map里
        dataSourceMap.put("user_center",dataSource0());
        //dataSourceMap.put("ds_0", createDataSource("ds_0"));
        //dataSourceMap.put("ds_1", createDataSource("ds_1"));
        //设置默认db为ds_0，也就是为那些没有配置分库分表策略的指定的默认库
        //如果只有一个库，也就是不需要分库的话，map里只放一个映射就行了，只有一个库时不需要指定默认库，但2个及以上时必须指定默认库，否则那些没有配置策略的表将无法操作数据
        //DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap, "ds_0");
        DataSourceRule dataSourceRule = new DataSourceRule(dataSourceMap);

        //设置分表映射，将t_user_0和t_user_1 t_user_2 三个实际的表映射到t_user逻辑表
        //0和1两个表是真实的表，t_order是个虚拟不存在的表，只是供使用。如查询所有数据就是select * from t_order就能查完0和1表的
        TableRule userTableRule = TableRule.builder("t_user")
                .actualTables(Arrays.asList("t_user_0", "t_user_1", "t_user_2"))
                .dataSourceRule(dataSourceRule)
                .build();

        List<TableRule> tableRuleList = new ArrayList<>();
        tableRuleList.add(userTableRule);

        //具体分库分表策略，按什么规则来分
        ShardingRule shardingRule = ShardingRule.builder()
                .dataSourceRule(dataSourceRule)
                .tableRules(tableRuleList)
//                .databaseShardingStrategy(new DatabaseShardingStrategy("user_id", new ModuloDatabaseShardingAlgorithm()))
                .tableShardingStrategy(new TableShardingStrategy("id", new ModuloTableShardingAlgorithm()))
                .build();



        DataSource dataSource = null;
        try {
            dataSource = ShardingDataSourceFactory.createDataSource(shardingRule);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return dataSource;
    }



}
